/*
 * JoinComponentDefinition.java
 *
 * Created on September 27, 2006, 11:37 PM
 *
 * (C) 2006 R. Alexander Milowski
 */

package com.smallx.xproc.library;

import com.smallx.xpath.XPathMatcherFactory;
import com.smallx.xproc.ComponentType;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import org.infoset.component.Component;
import org.infoset.component.ComponentBase;
import org.infoset.component.ComponentDefinition;
import org.infoset.xml.Document;
import org.infoset.xml.Item;
import org.infoset.xml.ItemDestination;
import org.infoset.xml.Name;
import org.infoset.xml.XMLException;
import org.infoset.xml.util.DocumentSource;

/**
 *
 * @author alex
 */
public class DebugComponentDefinition implements ComponentDefinition {

   static ComponentType defaultType = new ComponentType(LibraryComponents.DEBUG_TYPE);
   public static Name INPUT_PORT = Name.create("input");
   public static Name OUTPUT_PORT = Name.create("outresultput");
   static {
      defaultType.addInputPort(INPUT_PORT,true);
      defaultType.addOutputPort(OUTPUT_PORT,true);
   }
   
   class Debug extends ComponentBase {
      
      ItemDestination output = null;
      Document inputDocument;
      
      Debug() {
         super(type.getName());
      }
      
      public void onStart() 
         throws XMLException
      {
         if (inputDocument!=null) {
            onDocumentInput(INPUT_PORT,inputDocument);
         }
      }
      
      public void bindResource(Name port, URI location) throws XMLException {
         try {
            inputDocument = context.getDocumentLoader().load(location);
         } catch (IOException ex) {
            throw new XMLException("I/O error on "+location,ex);
         }
      }

      public void bindResource(Name port, Document doc) throws XMLException {
         inputDocument = doc;
      }
   
      public void bindOutputPort(Name port, ItemDestination output) throws XMLException {
         this.output = output;
      }
   
      public ItemDestination getInputPort(Name port) 
         throws XMLException
      {
         return new ItemDestination() {
            public void send(Item item) 
               throws XMLException
            {
               context.getLog().info(item.getType()+" "+item.toString());
               if (output!=null) {
                  output.send(item);
               } else if (item.getType()==Item.ItemType.DocumentItem) {
                  context.getLog().warning("There is no output for the debug.");
               }
            }
         };
      }

      public void onDocumentInput(Name port, Document doc) 
         throws XMLException 
      {
         DocumentSource.generate(doc,false,getInputPort(OUTPUT_PORT));
      }
   
   }
   protected ComponentType type;
   protected XPathMatcherFactory expression;
   
   public DebugComponentDefinition() {
      this(defaultType);
   }
   /** Creates a new instance of FlowComponentDefinition */
   public DebugComponentDefinition(ComponentType type) {
      this.type = type;
   }
   
   public void setExpression(XPathMatcherFactory exp) {
      this.expression = exp;
   }
   
   public Component newInstance()
      throws XMLException 
   {
      return new Debug();
   }
      
   public Name getName() {
      return type.getName();
   }

   public String getVersion() {
      return null;
   }

   public String getVendor() {
      return null;
   }

   public URI getVendorLocation() {
      return null;
   }

   public Collection<Name> getInputs() {
      return type.getInputPortNames();
   }

   public Collection<Name> getOutputs() {
      return type.getOutputPortNames();
   }

}

